package mcu.market.net;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.fluent.Request;
import org.apache.http.util.EntityUtils;
import org.apache.ibatis.exceptions.IbatisException;
import org.apache.ibatis.session.SqlSession;

import mcu.market.ibatis.IBatisFactory;
import mcu.market.ibatis.bean.BeanCompany;
import mcu.market.ibatis.bean.BeanDailyPrice;
import mcu.market.net.model.getPriceDataModel;
import mcu.market.util.DateUtil;

public class getOTCPrice extends getPriceDataModel{
	String init_date="2009-01-01";
	public getOTCPrice() {
		super.setCompanyList(super.OTC);
	}
	@Override
	public void execute() {
		String start = ""; 
		Date end = super.checkData();
		DateUtil du=new DateUtil();
		String URLcontent=null;
		List paserData=null;
		if(getLastDay()!=null){
			start=du.DateToString(getLastDay(), "yyyy-MM-dd");
		}
		try {
			if(!du.StringToDate(start, "yyyy-MM-dd").after(checkData())){
				List<Date> listDate = getDatesBetweenTwoDate(du.StringToDate(start, "yyyy-MM-dd"), end);
				if(start.equals(du.DateToString(end, "yyyy-MM-dd"))){listDate.remove(0);};
				for(Date date:listDate){ 
					String twday=tirmDay(du.DateToString(du.convertADDateToTWDate(du.DateToString(date, "yyyy/MM/dd")),"yyyy/MM/dd"));
					super.print(twday); 
					URLcontent=getDataFromURL(twday);
					paserData=paserData(URLcontent,null);
					insertDataToDB(paserData,date);
				} 
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public String getDataFromURL(Object parameter) {
		String content=null;
		try {
	        ResponseHandler<String> myHandler = new ResponseHandler<String>() {
	        	@Override
	        	public String handleResponse(
	        	        final HttpResponse response) throws IOException {
	        	    return EntityUtils.toString(response.getEntity(), Consts.UTF_8);
	        	}
	        };
	        content= Request.Get("http://www.otc.org.tw/ch/stock/aftertrading/otc_quotes_no1430/stk_wn1430_result.php?d="+parameter+"&sect=AL")
	        		.execute().handleResponse(myHandler);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return content;
	}

	@Override
	public List paserData(String content, Object parameter) {
		List<Object> list=new ArrayList<Object>();	
		content=content.substring(content.indexOf("["));
		list =praserObject(content);
		return list;
	}

	@Override
	public void insertDataToDB(List paserJSON, Object parameter) {
		if(paserJSON.size()==1){
			return;
		}
		HashMap<String, Object> map=new HashMap<String, Object>();
		SqlSession sqlSession=IBatisFactory.getInstance().getSqlSession();
		List list=getCompanyList();
		for(Object obj:list){
			map.put(String.valueOf(((BeanCompany)obj).getSid()), null);
		}
		for(Object obj:paserJSON){
			
			if(map.containsKey((String)((List)obj).get(0))){
				map.put((String)((List)obj).get(0), obj);
			}
		}
		Iterator it = map.entrySet().iterator();
	    while (it.hasNext()) {
	    	Map.Entry obj = (Map.Entry) it.next();
	    	BeanDailyPrice BDP=new BeanDailyPrice();
	    	if(obj.getValue()!=null){
		    	BDP.setSid(Integer.parseInt((String)obj.getKey()));
				BDP.setDay((Date)parameter);
				if("----".equals((((String)((List)obj.getValue()).get(2)).trim()))||"---".equals((((String)((List)obj.getValue()).get(3)).trim()))){
					BDP.setClose(0.0);
					BDP.setD_price(0.0);
					BDP.setOpen(0.0);
					BDP.setHigh(0.0);
					BDP.setLow(0.0);
				}else{
					BDP.setClose(Double.parseDouble(((String)((List)obj.getValue()).get(2)).trim()));
					Double dp;
					dp=("\\u9664\\u6b0a".equals(((String)((List)obj.getValue()).get(3)).replace(" ", ""))
							||"\\u9664\\u606f".equals(((String)((List)obj.getValue()).get(3)).replace(" ", ""))
							||"\\u9664\\u6b0a\\u606f".equals(((String)((List)obj.getValue()).get(3)).replace(" ", "")))?null:Double.parseDouble(((String)((List)obj.getValue()).get(3)).replace(" ", ""));
					BDP.setD_price(dp);
					BDP.setOpen(Double.parseDouble(((String)((List)obj.getValue()).get(4)).trim()));
					BDP.setHigh(Double.parseDouble(((String)((List)obj.getValue()).get(5)).trim()));
					BDP.setLow(Double.parseDouble(((String)((List)obj.getValue()).get(6)).trim()));
				}
				BDP.setVolume(Long.parseLong(((String)((List)obj.getValue()).get(7)).replaceAll(",", "")));
				BDP.setM_totle(Long.parseLong(((String)((List)obj.getValue()).get(8)).replaceAll(",", "")));
				BDP.setM_count(Long.parseLong(((String)((List)obj.getValue()).get(9)).replaceAll(",", "")));
				try{
					sqlSession.insert("insertDailyPrice",BDP);
				}catch(Exception e){
					break;
				}
				System.out.println(obj.getKey()+","+obj.getValue());
			}
	    	
	    }
	    sqlSession.commit();
	    sqlSession.close();
		
	}
	
	private Date getLastDay() {
		SqlSession sqlSession=IBatisFactory.getInstance().getSqlSession();
		List<BeanCompany> list= getCompanyList();
		Date date =null;
		for(BeanCompany bean:list){
			try{
				Date data_date =(Date) sqlSession.selectOne("daily_price.selectLastDay",bean);
				
				if((data_date!=null&&date==null)||(data_date!=null&&data_date.after(date))){
					Calendar calendar = Calendar.getInstance();
					calendar.setTime(data_date);
				    calendar.add(Calendar.DATE, +1);
				    date = calendar.getTime();
				}
			}catch(IbatisException e){
				sqlSession.close();
				sqlSession=IBatisFactory.getInstance().getSqlSession();
				Map map=new HashMap();
				map.put("sid", String.valueOf(bean.getSid()));
				map.put("sid_k", String.valueOf(bean.getSid()+"_pkey"));
				sqlSession.insert("daily_price.CreateDailyPrice",map);
				sqlSession.commit();
			}
		}
		return date;
	}
	public String tirmDay(String day){
		int i=0;
		while('0'==day.charAt(i)){
			i++;
		}
		return day.substring(i);
		
	}
	public List praserObject(String str){
		List<Object> list=new ArrayList<Object>();
		Object temp="";
		boolean lock=false;
		for(int i=0;i<str.length();i++){
			if('"'==str.charAt(i)&&!lock){
				lock=true;
			}
			else if('"'==str.charAt(i)&&lock){
				lock=false;
			}else if('['==str.charAt(i)&&!lock){
				i++;
				str.charAt(i);
				List l=praserObject(str.substring(i));
				i=i+(int)l.get((l.size()-1));
				l.remove(l.size()-1);
				temp=l;
			}else if(']'==str.charAt(i)&&!lock){
				list.add(temp);
				list.add(i);
				temp="";
				break;
			}else if(','==str.charAt(i)&&!lock){
				list.add(temp);
				temp="";
			}else if(temp instanceof String){
				temp=(String)temp+str.charAt(i);
			}
		}
		if(list.size()==0){
			return (List) temp;
		}
		return list;
	}
	
	public List getDatesBetweenTwoDate(Date beginDate, Date endDate) {  
		List lDate = new ArrayList();  
		lDate.add(beginDate);
		Calendar cal = Calendar.getInstance();  
		cal.setTime(beginDate);  
		boolean bContinue = true;  
		while (bContinue) {  
		cal.add(Calendar.DAY_OF_MONTH, 1);  
			if (endDate.after(cal.getTime())) {  
				lDate.add(cal.getTime());  
			} else {  break;  }  
		}  
		lDate.add(endDate);
		return lDate;  
	}  
	

	/*/**
	     * unicode转字符串
	     * @param str
	     * @return
	     *
	    public static String unicode2Str(String str) {
	        StringBuffer sb = new StringBuffer();
	        String[] arr = str.split("\\\\u");
	        int len = arr.length;
	        sb.append(arr[0]);
	        for(int i=1; i<len; i++){
	            String tmp = arr[i];
	            char c = (char)Integer.parseInt(tmp.substring(0, 4), 16);
	            sb.append(c);
	            sb.append(tmp.substring(4));
	        }
	        return sb.toString();
	    }*/
}
/*
710597代號
V2\u6c38\u8c50名稱
0.60收盤
+ 0.02 漲跌
0.59開盤
0.60最高
0.57最低
36,000成交股數
21,150成交金額(元)
3成交筆數
0.59最後買價
0.60最後賣價
9,000,000發行股數
0.86次日漲停價
0.34次日跌停價
*/
